home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume3 / egetopt < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  19.2 KB

  1. Path: xanth!mcnc!gatech!bloom-beacon!tut.cis.ohio-state.edu!husc6!necntc!ncoast!allbery
  2. From: ljz@ames.arc.nasa.gov@@uunet.uu.net:fxgrp.UUCP
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i016: egetopt: extended getopt()
  5. Message-ID: <8805140225.AA09152@fxgrp.fx.com>
  6. Date: 14 May 88 02:25:27 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: ljz@ames.arc.nasa.gov@@uunet.uu.net:fxgrp.UUCP
  9. Lines: 636
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. comp.sources.misc: Volume 3, Issue 16
  13. Submitted-By: "A. Nonymous" <ljz@ames.arc.nasa.gov@@uunet.uu.net:fxgrp.UUCP>
  14. Archive-Name: egetopt
  15.  
  16. I hope you'll see fit to post this to comp.sources.unix:
  17.  
  18. Due to the recent discussion in comp.lang.c about the deficiencies of
  19. getopt(), I have created an extended getopt() called "egetopt()".  Its
  20. default behavior is exactly the same as that of getopt(), but
  21. interested users can also make use of several useful extensions.
  22.  
  23. For those of you who believe getopt() is perfect and should never be
  24. improved, egetopt() will mirror its behavior.  For those of you who
  25. would like something better, I hope you will be satisfied with the
  26. added capabilities of egetopt().
  27.  
  28. This has made it through testing, but it may still have a bug or two.
  29. It has no man page as yet ... would some kind soul be willing to write
  30. one?  It does have a README file which describes its features,
  31. however.
  32.  
  33. Enjoy.
  34.  
  35. --
  36.     Lloyd Zusman
  37.     Master Byte Software
  38.     Los Gatos, California        Internet: ljz@fx.com
  39.     "We take things well in hand."    UUCP:     ...!ames!fxgrp!ljz
  40.  
  41. #--------------------------Cut Here--------------------------
  42. #! /bin/sh
  43. # This is a shell archive.  Remove anything before the "#! /bin/sh" line,
  44. # then unpack it by saving it in a file and typing "sh file."
  45. #
  46. # Wrapped by Lloyd Zusman (ljz) at fxgrp on Fri May 13 19:08:18 1988
  47. #
  48. # unpacks with default permissions
  49. #
  50. # Contents : README Makefile demo.c egetopt.c
  51. #
  52. if `test ! -s README`
  53. then
  54. echo "x - README"
  55. sed 's/^X//' > README << '@\END_OF_FILE_README'
  56. Xegetopt.c -- Extended 'getopt'.
  57. X
  58. XA while back, a public-domain version of getopt() was posted to the
  59. Xnet.  A bit later, a gentleman by the name of Keith Bostic made some
  60. Xenhancements and reposted it.
  61. X
  62. XIn recent weeks (i.e., early-to-mid 1988) there has been a sometimes
  63. Xheated discussion in comp.lang.c about the merits and drawbacks of
  64. Xgetopt(), especially with regard to its handling of '?'.
  65. X
  66. XIn light of this, I have taken Mr. Bostic's public-domain getopt()
  67. Xand have made some changes that I hope will be considered to be
  68. Ximprovements.  I call this routine 'egetopt' ("Extended getopt").
  69. XThe default behavior of this routine is the same as that of getopt(),
  70. Xbut it has some optional features that make it more useful.  These
  71. Xoptions are controlled by the settings of some global variables.
  72. XBy not setting any of these extra global variables, you will have
  73. Xthe same functionality as getopt(), which should satisfy those
  74. Xpurists who believe getopt() is perfect and can never be improved.
  75. XIf, on the other hand, you are someone who isn't satisfied with the
  76. Xstatus quo, egetopt() may very well give you the added capabilities
  77. Xyou want.
  78. X
  79. Xegetopt() behaves like getopt() with the following added capabilities:
  80. X
  81. X--    The '?' which gets returned when there is an unrecognized option
  82. X    is now stored in a global integer called 'optbad', and the caller
  83. X    can set this value to anything.  The initial value in 'optbad' is
  84. X        '?', which means that the default behavior is just like that of
  85. X        getopt().  For example, If you want egetopt() to return '~'
  86. X        instead of '?' when it sees an invalid option, put the following
  87. X        lines in your code before egetopt() gets called:
  88. X
  89. X        extern int optbad;
  90. X        optbad = (int)'~';
  91. X
  92. X--    Options can begin with characters other than just '-'.  There
  93. X    is now a global character pointer called 'optstart'.  It points
  94. X    to a string which consists of a list of characters which can
  95. X    be used to begin options.  The initial string that 'optstart'
  96. X    points to is "-", so the default behavior is like that of
  97. X        getopt().  For example, if you want to allow both '+' and '-'
  98. X        as option delimiters, put the following lines in your code
  99. X        before egetopt() gets called:
  100. X
  101. X        extern char *optstart;
  102. X        optstart = "-+";
  103. X
  104. X--    Now that there's a choice of the characters that can precede options
  105. X    it's desirable to let the caller know what character begins a
  106. X    given option.  In egetopt(), the global integer 'optchar' will
  107. X    now contain the character that begins a given option, or 0 if
  108. X    there was an error.  Just put the following line in your code
  109. X    and you can check the value of 'optchar' after each call to
  110. X    egetopt():
  111. X
  112. X        extern int optchar;
  113. X
  114. X--    The old getopt() writes error messages to file descriptor 2
  115. X    (or to stderr, depending on your implementation).  In egetopt(),
  116. X    you can change this file descriptor to be anything you want.
  117. X    The global integer 'opterrfd' contains the file descriptor
  118. X    to use for writing error messages.  As you might have guessed,
  119. X    this variable is initialized to 2.  As an example, if you want
  120. X    your egetopt() errors to go to the file "egetopt.errs", do
  121. X        something similar to the following before calling egetopt():
  122. X
  123. X        extern int opterrfd;
  124. X
  125. X        FILE *eout = fopen("egetopt.errs", "w");
  126. X
  127. X        if (eout == (FILE)NULL) {
  128. X            /* error condition/
  129. X            ...
  130. X            exit(1);
  131. X        }
  132. X
  133. X        opterrfd = fileno(eout);
  134. X
  135. X--    Some implementations of getopt() allow you to set the global
  136. X    integer 'opterr' to control whether error output is printed:
  137. X    it is initialized to 1, which enables error output (as does
  138. X    any non-zero value); setting it to 0 disables error output.
  139. X    In egetopt(), 'opterr' is treated the same way.
  140. X
  141. X--    The old getopt() forces you to use ':' in the string of option
  142. X    letters to show that a given option takes an argument.  There is
  143. X    now a global integer called 'optneed' which contains this value,
  144. X    so you can change it to something else if you want.  As you might
  145. X        have suspected, 'optneed' is initialized to ':'.
  146. X
  147. X    In addition, something that I always found annoying about the old
  148. X    getopt() is its inability to handle non-mandatory option arguments.
  149. X    For example, if an option called 'd' was specified as taking
  150. X    an argument to the program 'foo', you'd get the following
  151. X    results when invoking 'foo' in different ways:
  152. X
  153. X    1)    foo -dABC -x ...
  154. X
  155. X            getopt() return:    'd'
  156. X            optarg:            "ABC"
  157. X
  158. X    2)    foo -dABC -x ...
  159. X
  160. X            getopt() return:    'd'
  161. X            optarg:            "ABC"
  162. X
  163. X    3)    foo -d -x ...
  164. X
  165. X        A)    getopt() return:    'd'
  166. X            optarg:            "-x"
  167. X
  168. X    In the case of number 3, sometimes one would prefer to get ...
  169. X
  170. X        B)    getopt() return:    'd'
  171. X            optarg:            NULL
  172. X
  173. X    This would allow "-x" to be handled as another option in the next
  174. X    call.  In the old getopt(), you can get the 3B behavior by testing
  175. X    the first character of 'optarg' and decrementing 'optind' if this
  176. X    character is '-'.  However, since I am enhancing the routine
  177. X        anyway, I decided to build in the ability to have either the 3A
  178. X        or the 3B behavior.
  179. X
  180. X    Since this behavior isn't always desired, I have added another
  181. X    global integer called 'optmaybe' which optionally allows you to
  182. X    control whether an option with an argument will get treated as number
  183. X    3A or as number 3B above.  It is used similarly to 'optneed'.  It is
  184. X    initialized to 0, meaning that behavior 3B is impossible in the
  185. X    default case.  The following example shows how 'optneed' and
  186. X    'optmaybe' can be used:
  187. X
  188. X                extern int optneed;
  189. X                   extern int optmaybe;
  190. X
  191. X                optneed = (int)'!';    /* use '!' instead of ':'/
  192. X        optmaybe = (int)'%';    /* use '%' for optional arguments/
  193. X
  194. X        ...
  195. X
  196. X        while ((c = egetopt(argc, argv, "abc!d%x")) != EOF) ...
  197. X
  198. X    In this example, options 'a', 'b', and 'x' take no arguments,
  199. X    option 'c' takes a mandatory argument, and option 'd' takes
  200. X    a non-mandatory argument.  If this is contained in program 'foo',
  201. X        you'll get the following behavior when you run it:
  202. X
  203. X        foo -a -cABC -dXYZ -d -x -c -b ...
  204. X
  205. X            egetopt() return:    'a'
  206. X            optarg:            NULL
  207. X
  208. X            egetopt() return:    'c'
  209. X            optarg:            "ABC"
  210. X
  211. X            egetopt() return:    'd'
  212. X            optarg:            "XYZ"
  213. X
  214. X    >>>>>>>>>>    egetopt() return:    'd'
  215. X    >>>>>>>>>>    optarg:            NULL
  216. X    >> NOTE >>
  217. X    >>>>>>>>>>    egetopt() return:    'x'
  218. X    >>>>>>>>>>    optarg:            NULL
  219. X
  220. X            egetopt() return:    'c'
  221. X            optarg:            "-b"
  222. X
  223. X            ...
  224. X
  225. X    Remember that 'optneed' is initialized to ':' and 'optmaybe'
  226. X    is initialized to 0.  This causes behavior identical to that
  227. X    of getopt() unless you specifically override it.
  228. X
  229. XSince the default behavior of egetopt() is the same as that of getopt(),
  230. Xthere is no reason why you can't rename this routine to getopt() and
  231. Xuse it in place of the original.  I gave it a new name so as not to
  232. Xoffend those of you who believe that getopt() is perfect and should
  233. Xnever have any new features added to it.
  234. X
  235. XThe code was originally posted to the net as getopt.c by ...
  236. X
  237. X    Keith Bostic
  238. X    ARPA: keith@seismo 
  239. X    UUCP: seismo!keith
  240. X
  241. XCurrent version: added enhancements and comments, reformatted code.
  242. X
  243. X    Lloyd Zusman
  244. X    Master Byte Software
  245. X    Los Gatos, California
  246. X    Internet:    ljz@fx.com
  247. X    UUCP:        ...!ames!fxgrp!ljz
  248. X
  249. X        May, 1988
  250. @\END_OF_FILE_README
  251. else
  252.   echo "shar: Will not over write README"
  253. fi
  254. if `test ! -s Makefile`
  255. then
  256. echo "x - Makefile"
  257. sed 's/^X//' > Makefile << '@\END_OF_FILE_Makefile'
  258. X#
  259. X# Makefile for building egetopt.o and a program that demonstrates it.
  260. X#
  261. XCFLAGS    =-g
  262. X
  263. Xall:    demo
  264. X
  265. Xegetopt.o:    egetopt.c
  266. X
  267. Xdemo.o:        demo.c
  268. X
  269. Xdemo:    demo.o egetopt.o
  270. X    cc -o demo demo.o egetopt.o
  271. @\END_OF_FILE_Makefile
  272. else
  273.   echo "shar: Will not over write Makefile"
  274. fi
  275. if `test ! -s demo.c`
  276. then
  277. echo "x - demo.c"
  278. sed 's/^X//' > demo.c << '@\END_OF_FILE_demo.c'
  279. X#include <stdio.h>
  280. X
  281. X/*
  282. X * This is a short program for demonstrating the capabilities of egetopt().
  283. X * Run it with various combinations of options and arguments on the command
  284. X * line to see how egetopt() works.
  285. X *
  286. X * Experiment around with this by changing some of my settings and
  287. X * recompiling.
  288. X */
  289. X
  290. X#define OPT_STRING    "abc~d~e?f?"
  291. X/* Meaning:
  292. X *
  293. X * -a and -b take no arguments.
  294. X * -c and -d take mandatory arguments (I set 'optneed' to '~', below).
  295. X * -e and -f take optional arguments (I set 'optmaybe' to '?', below).
  296. X */
  297. X
  298. X#define OPT_CHARS    "-+="
  299. X/* Meaning:
  300. X *
  301. X * Options can begin with '-', '+', or '='.
  302. X */
  303. X
  304. X
  305. X/*
  306. X * New global variables used in egetopt() only:
  307. X */
  308. Xextern int optneed;    /* character used for mandatory arguments */
  309. Xextern int optmaybe;    /* character used for optional arguments */
  310. Xextern int optchar;    /* character which begins a given argument */
  311. Xextern int optbad;    /* what egetopt() returns for a bad option */
  312. Xextern int opterrfd;    /* where egetopt() error messages go */
  313. Xextern char *optstart;    /* string which contains valid option start chars */
  314. X
  315. X/*
  316. X * Global variables which exist in getopt() and egetopt():
  317. X */
  318. Xextern int optind;    /* index of current argv[] */
  319. Xextern int optopt;    /* the actual option pointed to */
  320. Xextern int opterr;    /* set to 0 to suppress egetopt's error messages */
  321. Xextern char *optarg;    /* the argument of the option */
  322. X
  323. Xmain(argc, argv)
  324. Xint argc;
  325. Xchar **argv;
  326. X{
  327. X    int ch;
  328. X
  329. X    opterrfd = fileno(stdout);    /* errors to stdout */
  330. X    opterr = 0;        /* set this to 1 to get egetopt's error msgs */
  331. X    optbad = '!';        /* return '!' instead of '?' on error */
  332. X    optneed = '~';        /* mandatory arg identifier (in OPT_STRING) */
  333. X    optmaybe = '?';        /* optional arg identifier (in OPT_STRING) */
  334. X    optstart = OPT_CHARS;    /* characters that can start options */
  335. X
  336. X    while ((ch = egetopt(argc, argv, OPT_STRING)) != EOF) {
  337. X        printf("\n\toption index (optind) after egetopt(): %5d\n",
  338. X            optind);
  339. X        printf("\t\tegetopt() return value:            %c (%d)\n",
  340. X            ch, ch);
  341. X        printf("\t\tchar that begins option (optchar): %c\n",
  342. X            optchar);
  343. X        printf("\t\tactual char looked at (optopt):    %c\n",
  344. X            optopt);
  345. X        printf("\t\toption argument:                   \"%s\"\n",
  346. X            optarg == NULL ? "(null)" : optarg);
  347. X    }
  348. X
  349. X    for (; optind < argc; ++optind) {
  350. X        printf("\n\targument index                         %5d\n",
  351. X            optind);
  352. X        printf("\t\targument:                          \"%s\"\n",
  353. X            argv[optind] == NULL ? "(null)" : argv[optind]);
  354. X    }
  355. X
  356. X    exit(0);
  357. X}
  358. @\END_OF_FILE_demo.c
  359. else
  360.   echo "shar: Will not over write demo.c"
  361. fi
  362. if `test ! -s egetopt.c`
  363. then
  364. echo "x - egetopt.c"
  365. sed 's/^X//' > egetopt.c << '@\END_OF_FILE_egetopt.c'
  366. X/*
  367. X * egetopt.c -- Extended 'getopt'.
  368. X *
  369. X * A while back, a public-domain version of getopt() was posted to the
  370. X * net.  A bit later, a gentleman by the name of Keith Bostic made some
  371. X * enhancements and reposted it.
  372. X *
  373. X * In recent weeks (i.e., early-to-mid 1988) there's been some
  374. X * heated discussion in comp.lang.c about the merits and drawbacks
  375. X * of getopt(), especially with regard to its handling of '?'.
  376. X *
  377. X * In light of this, I have taken Mr. Bostic's public-domain getopt()
  378. X * and have made some changes that I hope will be considered to be
  379. X * improvements.  I call this routine 'egetopt' ("Extended getopt").
  380. X * The default behavior of this routine is the same as that of getopt(),
  381. X * but it has some optional features that make it more useful.  These
  382. X * options are controlled by the settings of some global variables.
  383. X * By not setting any of these extra global variables, you will have
  384. X * the same functionality as getopt(), which should satisfy those
  385. X * purists who believe getopt() is perfect and can never be improved.
  386. X * If, on the other hand, you are someone who isn't satisfied with the
  387. X * status quo, egetopt() may very well give you the added capabilities
  388. X * you want.
  389. X *
  390. X * Look at the enclosed README file for a description of egetopt()'s
  391. X * new features.
  392. X *
  393. X * The code was originally posted to the net as getopt.c by ...
  394. X *
  395. X *    Keith Bostic
  396. X *    ARPA: keith@seismo 
  397. X *    UUCP: seismo!keith
  398. X *
  399. X * Current version: added enhancements and comments, reformatted code.
  400. X *
  401. X *    Lloyd Zusman
  402. X *    Master Byte Software
  403. X *    Los Gatos, California
  404. X *    Internet:    ljz@fx.com
  405. X *    UUCP:        ...!ames!fxgrp!ljz
  406. X *
  407. X *        May, 1988
  408. X */
  409. X
  410. X/*
  411. X * If you want, include stdio.h or something where EOF and NULL are defined.
  412. X * However, egetopt() is written so as not to need stdio.h, which should
  413. X * make it significantly smaller on some systems.
  414. X */
  415. X
  416. X#ifndef EOF
  417. X# define EOF        (-1)
  418. X#endif /* ! EOF */
  419. X
  420. X#ifndef NULL
  421. X# define NULL        (char *)0
  422. X#endif /* ! NULL */
  423. X
  424. X/*
  425. X * None of these constants are referenced in the executable portion of
  426. X * the code ... their sole purpose is to initialize global variables.
  427. X */
  428. X#define BADCH        (int)'?'
  429. X#define NEEDSEP        (int)':'
  430. X#define MAYBESEP    (int)'\0'
  431. X#define ERRFD        2
  432. X#define EMSG        ""
  433. X#define START        "-"
  434. X
  435. X/*
  436. X * Here are all the pertinent global variables.
  437. X */
  438. Xint opterr = 1;        /* if true, output error message */
  439. Xint optind = 1;        /* index into parent argv vector */
  440. Xint optopt;        /* character checked for validity */
  441. Xint optbad = BADCH;    /* character returned on error */
  442. Xint optchar = 0;    /* character that begins returned option */
  443. Xint optneed = NEEDSEP;    /* flag for mandatory argument */
  444. Xint optmaybe = MAYBESEP;/* flag for optional argument */
  445. Xint opterrfd = ERRFD;    /* file descriptor for error text */
  446. Xchar *optarg;        /* argument associated with option */
  447. Xchar *optstart = START;    /* list of characters that start options */
  448. X
  449. X
  450. X/*
  451. X * Macros.
  452. X */
  453. X
  454. X/*
  455. X * Conditionally print out an error message and return (depends on the
  456. X * setting of 'opterr' and 'opterrfd').  Note that this version of
  457. X * TELL() doesn't require the existence of stdio.h.
  458. X */
  459. X#define TELL(S)    { \
  460. X    if (opterr && opterrfd >= 0) { \
  461. X        char option = optopt; \
  462. X        write(opterrfd, *nargv, strlen(*nargv)); \
  463. X        write(opterrfd, (S), strlen(S)); \
  464. X        write(opterrfd, &option, 1); \
  465. X        write(opterrfd, "\n", 1); \
  466. X    } \
  467. X    return (optbad); \
  468. X}
  469. X
  470. X/*
  471. X * This works similarly to index() and strchr().  I include it so that you
  472. X * don't need to be concerned as to which one your system has.
  473. X */
  474. Xstatic char *
  475. X_sindex(string, ch)
  476. Xchar *string;
  477. Xint ch;
  478. X{
  479. X    if (string != NULL) {
  480. X        for (; *string != '\0'; ++string) {
  481. X            if (*string == (char)ch) {
  482. X                return (string);
  483. X            }
  484. X        }
  485. X    }
  486. X
  487. X    return (NULL);
  488. X}
  489. X
  490. X/*
  491. X * Here it is:
  492. X */
  493. Xint
  494. Xegetopt(nargc, nargv, ostr)
  495. Xint nargc;
  496. Xchar **nargv;
  497. Xchar *ostr;
  498. X{
  499. X    static char *place = EMSG;    /* option letter processing */
  500. X    register char *oli;        /* option letter list index */
  501. X    register char *osi = NULL;    /* option start list index */
  502. X
  503. X    if (nargv == (char **)NULL) {
  504. X        return (EOF);
  505. X    }
  506. X
  507. X    if (nargc <= optind || nargv[optind] == NULL) {
  508. X        return (EOF);
  509. X    }
  510. X
  511. X    if (place == NULL) {
  512. X        place = EMSG;
  513. X    }
  514. X
  515. X    /*
  516. X     * Update scanning pointer.
  517. X     */
  518. X    if (*place == '\0') {
  519. X        place = nargv[optind];
  520. X        if (place == NULL) {
  521. X            return (EOF);
  522. X        }
  523. X        osi = _sindex(optstart, *place);
  524. X        if (osi != NULL) {
  525. X            optchar = (int)*osi;
  526. X        }
  527. X        if (optind >= nargc || osi == NULL || *++place == '\0') {
  528. X                return (EOF);
  529. X        }
  530. X
  531. X        /*
  532. X         * Two adjacent, identical flag characters were found.
  533. X         * This takes care of "--", for example.
  534. X         */
  535. X        if (*place == place[-1]) {
  536. X            ++optind;
  537. X            return (EOF);
  538. X        }
  539. X    }
  540. X
  541. X    /*
  542. X     * If the option is a separator or the option isn't in the list,
  543. X     * we've got an error.
  544. X     */
  545. X    optopt = (int)*place++;
  546. X    oli = _sindex(ostr, optopt);
  547. X    if (optopt == optneed || optopt == optmaybe || oli == NULL) {
  548. X        /*
  549. X         * If we're at the end of the current argument, bump the
  550. X         * argument index.
  551. X         */
  552. X        if (*place == '\0') {
  553. X            ++optind;
  554. X        }
  555. X        TELL(": illegal option -- ");    /* byebye */
  556. X    }
  557. X
  558. X    /*
  559. X     * If there is no argument indicator, then we don't even try to
  560. X     * return an argument.
  561. X     */
  562. X    ++oli;
  563. X    if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
  564. X        /*
  565. X         * If we're at the end of the current argument, bump the
  566. X         * argument index.
  567. X         */
  568. X        if (*place == '\0') {
  569. X            ++optind;
  570. X        }
  571. X        optarg = NULL;
  572. X    }
  573. X    /*
  574. X     * If we're here, there's an argument indicator.  It's handled
  575. X     * differently depending on whether it's a mandatory or an
  576. X     * optional argument.
  577. X     */
  578. X    else {
  579. X        /*
  580. X         * If there's no white space, use the rest of the
  581. X         * string as the argument.  In this case, it doesn't
  582. X         * matter if the argument is mandatory or optional.
  583. X         */
  584. X        if (*place != '\0') {
  585. X            optarg = place;
  586. X        }
  587. X        /*
  588. X         * If we're here, there's whitespace after the option.
  589. X         *
  590. X         * Is it a mandatory argument?  If so, return the
  591. X         * next command-line argument if there is one.
  592. X         */
  593. X        else if (*oli == optneed) {
  594. X            /*
  595. X             * If we're at the end of the argument list, there
  596. X             * isn't an argument and hence we have an error.
  597. X             * Otherwise, make 'optarg' point to the argument.
  598. X             */
  599. X            if (nargc <= ++optind) {
  600. X                place = EMSG;
  601. X                TELL(": option requires an argument -- ");
  602. X            }
  603. X            else {
  604. X                optarg = nargv[optind];
  605. X            }
  606. X        }
  607. X        /*
  608. X         * If we're here it must have been an optional argument.
  609. X         */
  610. X        else {
  611. X            if (nargc <= ++optind) {
  612. X                place = EMSG;
  613. X                optarg = NULL;
  614. X            }
  615. X            else {
  616. X                optarg = nargv[optind];
  617. X                if (optarg == NULL) {
  618. X                    place = EMSG;
  619. X                }
  620. X                /*
  621. X                 * If the next item begins with a flag
  622. X                 * character, we treat it like a new
  623. X                 * argument.  This is accomplished by
  624. X                 * decrementing 'optind' and returning
  625. X                 * a null argument.
  626. X                 */
  627. X                else if (_sindex(optstart, *optarg) != NULL) {
  628. X                    --optind;
  629. X                    optarg = NULL;
  630. X                }
  631. X            }
  632. X        }
  633. X        place = EMSG;
  634. X        ++optind;
  635. X    }
  636. X
  637. X    /*
  638. X     * Return option letter.
  639. X     */
  640. X    return (optopt);
  641. X}
  642. @\END_OF_FILE_egetopt.c
  643. else
  644.   echo "shar: Will not over write egetopt.c"
  645. fi
  646. # to concatenate archives, remove anything after this line
  647. exit 0
  648.